home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pnl010.zip / TEST186.PAS < prev    next >
Pascal/Delphi Source File  |  1992-03-01  |  4KB  |  118 lines

  1. (*  Code from m274.
  2. (117)   Thu 6 Jun 91  3:30a
  3. By: Robert Mashlan
  4. To: All
  5. Re: TEST286.PAS
  6. St:                                                              Reply in  118
  7. -----------------------------------------------------------------------------
  8. @EID:522d 16c61bcf
  9. @MSGID: 1:147/38 63036254
  10. Hello All,
  11.  
  12. It was brought to my attention by Michelango Jones that Borland's Test286.pas
  13. demo program was provided by Borland such than you can provide a stub function
  14. for a program compiled with {$G+}.  The problem with this code is that is
  15. unfairly leaves out lesser CPUs capable of running this code.
  16.  
  17. If you use {$G+}, please feel free to use this code!
  18.  
  19. ===========================================================
  20. *)
  21.  
  22. {$G+}
  23. Unit Test186;
  24.  
  25. (*   test186.pas     6-6-91  Robert Mashlan
  26.  
  27.      license: to public domain
  28.  
  29.      This unit provides a stub function for code compiled with TP 6.0's
  30.      "286" code generation directive {$G-}.  Borland provides a demo
  31.      program called TEST286.PAS that checks if the machine is a 286 or
  32.      better, but leaves out the 80186/80188/V20/V30 machines perfectly
  33.      capable of running code compiled in this mode.
  34.  
  35.      To use this unit, simply place it as the first unit listed in a {$G+}
  36.      program's unit clause.  If the CPU is not capable of running the
  37.      program, it will abort.
  38.  
  39. *)
  40.  
  41.  
  42. Interface
  43.  
  44. Implementation
  45.  
  46. Function Is186Able : boolean; assembler;
  47. (* This function returns true if the CPU is not a 8088/8086, which
  48.    cannot run code compiled in {$G+} mode.  A NEC V20, V30,
  49.    Intel 80186, 80188, 286, 386, and 486 can all run TP 6.0's
  50.    "286" code and return true.
  51. *)
  52. asm
  53.        pushf                   ;(* save flags  */
  54.  
  55.    (* This test differentiates between a 286 and up and an 80186 and below
  56.       This is done by checking the value of bits 12-15 in the flag register
  57.       when it is pushed onto the stack.   If they are set, then the CPU
  58.       is not a 286 and up.
  59.  
  60.    *)
  61.  
  62.        xor  ax,ax              ;(*  set ax=0            *)
  63.        push ax                 ;(*  push onto stack     *)
  64.        popf                    ;(*  pop flags           *)
  65.        pushf                   ;(*  push flags          *)
  66.        pop  ax                 ;(*  pop into ax         *)
  67.        and  ax,0f000h          ;(*  mask upper 4 bits   *)
  68.        cmp  ax,0f000h          ;(*  are bits 12-15 set? *)
  69.        jne  @exit186           ;(*  NO: is a 286 and up *)
  70.  
  71.  
  72. (*  This test differentiates a 80186/80188 between a V20/V30/8088/8086.
  73.     The 80186/80188 will clear the upper three bits of the shift count
  74.     before executing a shift instruction using the cl register.
  75. *)
  76.  
  77.        mov  al,0ffh            ;(* set all bits in al     *)
  78.        mov  cl,021h            ;(* try shifting 21h times *)
  79.        shr  al,cl              ;(* try shifting           *)
  80.        jne  @exit186           ;(* if al!=0 then it is a 80186/80188 *)
  81.  
  82. (*  This test differentiates the NEC V20/V30 between the 8088/8086
  83.  
  84.     This is done by testing for a bug in the 8088/8086.  In the
  85.     Intel CPUs, if a repeated string instruction with a segment
  86.     override is interrupted by a hardware interrupt, the
  87.     instruction is not continued.
  88. *)
  89.        sti                     ;(* enable interrupts *)
  90.        push si                 ;(* save si ( could be a register variable) *)
  91.        mov  si,0               ;(* Starting with first byte in es  *)
  92.        mov  cx,0ffffh          ;(* read a complete segment *)
  93.        db   0f3h, 26h, 0ach;
  94.        { rep lodsb es:[si] }   ;(* rep with a segment override *)
  95.        (* hardware interrupt is sure to occur during the above instruction *)
  96.        pop  si                 ;(* restore si  *)
  97.        or   cx,cx              ;(* has entire segment been read? *)
  98.        je   @exit186           ;(* YES: V20 or V30 *)
  99.                                 (* NO:  must be 8088 or 8086 *)
  100.  
  101. @exitnot186:
  102.        mov ax, 0;              ; (* return false *)
  103.        jmp @exit
  104.  
  105. @exit186:
  106.        mov  ax,01h             ;(* return true *)
  107. @exit:                         ;
  108.        popf                    ;(* restore flags *)
  109. end;
  110.  
  111. begin
  112.    if not Is186Able then
  113.    begin
  114.      Writeln('This program will not run on an 8088/8086.');
  115.      Halt(1);
  116.    end;
  117. end.
  118.